package co.edu.unal.bioingenium.kbmed.web.components.tree;

import co.edu.unal.bioingenium.kbmed.knowledge.vo.Concept;
import com.icesoft.faces.component.tree.IceUserObject;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
import javax.faces.event.ActionEvent;

/**
 * <p>The <code>NodeUserObject</code> represents a nodes user object.  This
 * particular IceUserobject implementation store extra information on how many
 * times the parent node is clicked on.  It is also responsible for copying and
 * delete its self.</p>
 * <p/>
 * <p>In this example pay particularly close attention to the
 * <code>wrapper</code> instance variable on IceUserObject.  The <code>wrapper</code>
 * allows for direct manipulations of the parent tree. </p>
 */
public class TreeNodeBean extends IceUserObject {

    private Concept concept;
    private TreeBean treeBean;

    /**
     * 
     * @param wrapper
     * @param tree
     */
    public TreeNodeBean(DefaultMutableTreeNode wrapper, TreeBean tree) {
        super(wrapper);
        treeBean = tree;
        setLeafIcon("content/img/c_gre.gif");
        setBranchContractedIcon("content/img/c_blu.gif");
        setBranchExpandedIcon("content/img/c_red.gif");
    }

    /**
     * 
     * @param wrapper
     * @param tree
     * @param name
     * @param isLeaf
     */
    public TreeNodeBean(DefaultMutableTreeNode wrapper, TreeBean tree, String name, boolean isLeaf) {
        super(wrapper);
        treeBean = tree;
        setLeafIcon("content/img/c_gre.gif");
        setBranchContractedIcon("content/img/c_blu.gif");
        setBranchExpandedIcon("content/img/c_red.gif");
        setText(name);
        setLeaf(isLeaf);
    }

    /**
     * Deletes this not from the parent tree.
     *
     * @param event that fired this method
     */
    public void deleteNode(ActionEvent event) {
        ((DefaultMutableTreeNode) getWrapper().getParent()).remove(getWrapper());
    }

    private void copyChildren(MutableTreeNode orig, MutableTreeNode clone) {
        int childCount = orig.getChildCount();
        while (childCount != 0) {
            childCount--;
            DefaultMutableTreeNode oldChild = (DefaultMutableTreeNode) orig.getChildAt(childCount);
            TreeNodeBean oldUserObject = (TreeNodeBean) oldChild.getUserObject();
            DefaultMutableTreeNode newChild = (DefaultMutableTreeNode) oldChild.clone();
            newChild.setUserObject(new TreeNodeBean(newChild, treeBean, oldUserObject.getText(), oldUserObject.isLeaf()));
            copyChildren(oldChild, newChild);
            clone.insert((MutableTreeNode) newChild, 0);
        }
    }

    /**
     * Copies this node and adds a it as a child node.
     *
     * @param event that fired this method
     */
    public void copyNode(ActionEvent event) {
        DefaultMutableTreeNode clonedWrapper = new DefaultMutableTreeNode();
        DefaultMutableTreeNode originalWrapper = getWrapper();

        TreeNodeBean originalUserObject = (TreeNodeBean) originalWrapper.getUserObject();
        TreeNodeBean clonedUserObject = new TreeNodeBean(clonedWrapper, treeBean, concept.getConceptId(), originalUserObject.isLeaf());

        clonedWrapper.setUserObject(clonedUserObject);
        copyChildren(originalWrapper, clonedWrapper);

        MutableTreeNode parentNode = ((MutableTreeNode) (originalWrapper.getParent()));
        if (parentNode != null) {
            parentNode.insert(clonedWrapper, 0);
        } else {
            originalWrapper.insert(clonedWrapper, 0);
        }
    }

    /**
     * Registers a user click with this object and updates the selected node in the TreeBean.
     *
     * @param event that fired this method
     */
    public void nodeClicked(ActionEvent event) {
        treeBean.setSelectedNodeObject(this);
    }
}
